home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / netz / ums / ums-beta / rexx / replydaemon.rexx < prev    next >
OS/2 REXX Batch file  |  1995-01-25  |  11KB  |  314 lines

  1. /* ------------------------------------------------------------------------
  2. :Program.    ReplyDaemon.rexx
  3. :Contents.   send receipt-reply messages depending on folder
  4. :Author.     hartmut Goebel [hG]
  5. :Address.    Aufsesßplatz 5, D-90459 Nürnberg
  6. :Address.    UseNet: hartmut@oberon.nbg.sub.org
  7. :History.    1.0  [hG] initial release
  8. :History.    1.1  [hG] · output onl if there are messages to process
  9. :History.              · no longer tests PostPone flag
  10. :History.    1.2  [hG] uses hgrexxsupport.library 1.2
  11. :History.    2.0  [hG] added optional check for ToName, adapted to UMS v11
  12. :Version.    $VER: ReplyDaemon.rexx 2.0 (25.1.95) [hG]
  13. :Copyright.  Public Domain
  14. :Language.   ARexx
  15. :Translator. RexxMast
  16. ------------------------------------------------------------------------ */
  17. /*
  18.  
  19. NAME
  20.      ReplyDaemon  --  send receipt-reply messages depending on folder
  21.  
  22. TEMPLATE
  23.      Name,Password,Server/K,UseReplyAccount/S,UseFolderAsReplyName/S
  24.  
  25. FUNCTION
  26.      ReplyDaemon checks for new messages within some given folders
  27.      and sends receipt-reply messages to the sender of these
  28.      messages. The checked messages will be marked as unread,
  29.      archived and postponed, thus both avoiding re-processing and
  30.      expiring.
  31.  
  32.      This is quite usefull for maintaining e.g. a bugs database where
  33.      the reporters should be given a receipt. You may use a tool like
  34.      Reciever2Folder to sort your messages into folders first and
  35.      then run ReplyDaemon to send the receipt-replies.
  36.  
  37.      The folders to be checked have to be listed in a config
  38.      variable. Also subject and body text for the message to be send
  39.      can be defined per folder via config vars.
  40.  
  41.      The receipt-reply may either be send from the users account or a
  42.      special ReplyDaemon account. The later is for avoiding garbage
  43.      messages in the user's mail folders.
  44.  
  45.      The Reply-Name put in the send message may get three values:
  46.      - the folder name (if option UseFolderAsReplyName is set)
  47.      - a reply name specified by a config var (see below)
  48.      - not set, thus later replies will get to either the user or the
  49.        ReplyDaemon, depenting on the option UsereplyAccount
  50.  
  51. OPTIONS
  52.      Name, Password, Server
  53.         are the normal UMS parameters
  54.  
  55.      UseReplyAccount
  56.         This option tells ReplyDaemon to send the messages not from
  57.         the users account but his own one. Thus it's possible to
  58.         expire the sent replies as soon as they are exported by
  59.         setting 'expire.mail = 0' the the ReplyDaeomn's account.
  60.  
  61.         The ReplyDaeomn's account must have an alias 'ReplyDaemon'
  62.         and require an empty password. Also WriteAccess must be set
  63.         correctly.
  64.  
  65.      UseFolderAsReplyName
  66.          This tells ReplyDaemon to set the ReplyName of send messages
  67.          to the name of the folder. The config-var
  68.          ReplyDaemon.ReplyName.<folder> will not be used then.
  69.  
  70. USED CONFIG-VARS
  71.  
  72.      ReplyDaemon.Folderlist          (required)
  73.           List of folders to be checked, form: FolderName [ "," ToName ]
  74.  
  75.           When specify an optional 'ToName' (seperated from the
  76.           folder name by a comma), only messages addressed to this
  77.           name are replied. Thus you can but all mail about a certain
  78.           project in one single folder and only the bugs get a
  79.           automatic reply.
  80.  
  81.      ReplyDaemon.Subject.<folder>    (required)
  82.      ReplyDaemon.MsgText.<folder>    (required)
  83.           Defines the subject and body text for the send-out message.
  84.           The body text will become preceded by an address ('Hi
  85.           <FromName>') plus one empty line and appended by one emtpy
  86.           line plus the text 'Of course, this message has been
  87.           generated automaticly :-)'.
  88.  
  89.      ReplyDaemon.ReplyName.<folder>  (optional)
  90.           If the option UseFolderAsReplyName is not set, this var
  91.           determines a ReplyName to be put into the send message.
  92.  
  93. EXAMPLE
  94.  
  95.      User
  96.         Name  "Mail-Daemon"
  97.        Alias "Reply-Daemon"
  98.        Password
  99.        NetAccess       = "#?"
  100.        expire.mail     = "0"
  101.        expire.private  = "0"
  102.        .... EndUser
  103.  
  104.      User
  105.        Name  "Joe User"
  106.        Password "noone"
  107.        Alias "ju"
  108.        Alias "project"
  109.        Alias "project-bugs"
  110.        Alias "info"
  111.        ....
  112.        ReplyDaemon.FolderList= "project, project-bugs*ninfo"
  113.        ReplyDaemon.ReplyName.Bugs = "ju"
  114.        ReplyDaemon.Subject.Bugs = "Recieved your bug report:"
  115.        ReplyDaemon.MsgText.Bugs= "Thank you for your bug report.*n
  116.                                   Joe User*NBugs Maintainer" ....
  117.        ReplyDaemon.Subject.Info = "Here's your Info"
  118.        ReplyDaemon.MsgText.Info= "Thank you for requesting the info*n
  119.                                   Joe User" ....
  120.      EndUser
  121.  
  122. TODO
  123.  
  124.  >* Es sollte auch die Möglichkeit geben, statt des Textes direkt (in
  125.  >  ums.config) einen FileNamen für ein Textfile anzugeben (z.B. statt
  126.  >  *.msgtext.* *.msgfile.*). Das bläht die config nicht garso
  127.  >  (unnötig) auf. Die Idee kam mir deshalb, weil man z.B. auf diese
  128.  >  Art ziemlich einfach längere (Info-)Files verschicken könnte, ohne
  129.  >  sie nach jeder Änderung zusätzlich in die ums.config quetschen zu
  130.  >  müssen. Ein schönes Beispiel wäre (dachte ich mir), den PGP public
  131.  >  key automatisiert zu verschicken, wenn jemand an
  132.  >  pgp@irgendwer.nbg.sub.org schreibt.
  133.  
  134. */
  135.  
  136. /*** Startup ***/
  137.  
  138. ProgramName = "ReplyDaemon";
  139. ArgsTemplate = "Name,Password,Server/K,UseReplyAccount/S,UseFolderAsReplyName/S"
  140. ReplyName = "Reply-Daemon";
  141. ReplyPassword = "";
  142.  
  143. call addlib("hgrexxsupport.library",0,-30);
  144. interpret include("ums:s/UMSInit.rexx")
  145. if rc ~= 0 then do
  146.   say "cannot read UMS include-file!"
  147.   exit 20
  148. end
  149.  
  150. /*** Login ***/
  151.  
  152. replyAccount = 0;
  153.  
  154. account = UMSLogin(name, password, server)
  155. if (account = 0) then do
  156.   say "unable to login."
  157.   exit 10
  158. end
  159.  
  160. if useReplyAccount then do
  161.   replyAccount = UMSLogin(replyName, ReplyPassword, server)
  162.   if (replyAccount = 0) then do
  163.     say "unable to login."
  164.     halt 10
  165.   end
  166. end; else
  167.   replyAccount = account
  168.  
  169. FLAGS_Empty = MakeFlags()
  170. FLAG_0 = MakeFlags(0)
  171. FLAG_1 = MakeFlags(1)
  172. FLAG_2 = MakeFlags(2)
  173. FLAGS_012 = MakeFlags(0,1,2)
  174. FLAG_Old = MakeFlags(UMSUSTAT_Old)
  175. FLAGS_PostArch = MakeFlags(UMSUSTAT_PostPoned,UMSUSTAT_Archive)
  176. Match = MakeFlags(UMSUSTAT_ViewAccess)
  177. Mask  = MakeFlags(UMSUSTAT_ViewAccess,/*UMSUSTAT_PostPoned,*/UMSUSTAT_Archive, UMSUSTAT_Old)
  178.  
  179. call UMSSelectField(account, "L", FLAG_0, FLAGS_Empty,,,UMSCODE_Group, "", TRUE)
  180. call UMSSelectFlags(account, "L", FLAG_1, FLAGS_Empty,,,"U", Mask, Match)
  181.  
  182. Folderlist = GetUMSConfigVar("","Folderlist", TRUE)
  183. do forever
  184.   parse var FolderList FolderName '0A'x Folderlist
  185.   FolderName = strip(FolderName)
  186.   if FolderName = '' then leave;
  187.   parse var FolderName FolderName ',' ToName
  188.   ToName = upper(ToName);
  189.   call ReplyOnMsgsInFolder;
  190. end
  191.  
  192. /*** Final cleanup ***/
  193.  
  194. BREAK_C:
  195. BREAK_D:
  196. BREAK_E:
  197. BREAK_F:
  198. ERROR:
  199. HALT:
  200. IOERR:
  201. SYNTAX:
  202.  
  203. IF RC ~= 0 THEN DO
  204.   say "Error: " rc errortext(rc) "Line" sigl
  205. END
  206.  
  207. /*** Logout ***/
  208.  
  209. call UMSLogout(account)
  210. if useReplyAccount then
  211.   call UMSLogout(replyAccount)
  212. exit
  213.  
  214. ReplyOnMsgsInFolder:
  215.   MessageText = GetUMSConfigVar(FolderName,"MsgText", TRUE)
  216.   Subject     = GetUMSConfigVar(FolderName,"Subject", TRUE)
  217.   ReplyName   = GetUMSConfigVar(FolderName,"ReplyName", FALSE)
  218.  
  219.   call UMSSelectFlags(account, "L", FLAGS_Empty, FLAG_2,,,"U", FLAGS_Empty, FLAGS_Empty)
  220.   call UMSSelectField(account, "L", FLAG_2, FLAGS_Empty,,,UMSCODE_Folder, FolderName)
  221.  
  222.   numTagedMsgs = UMSSelectFlags(account, "L", FLAGS_Empty, FLAGS_Empty,,,"L", FLAGS_012, FLAGS_012)
  223.  
  224.   if numTagedMsgs = 0 then return
  225.  
  226.   say ProgramName || ":" numTagedMsgs "messages in folder" FolderName "found"
  227.   i=0;last = 0
  228.   do forever
  229.     last = UMSSearchFlags(account, "L", FLAGS_012, FLAGS_012, last)
  230.     if last = 0 then leave /* we are done */
  231.  
  232.     drop msg. /* _IMPORTANT_ */
  233.     if ~ UMSReadMsgHeader(account, last, msg.,true) then do
  234.       call CheckErr
  235.       exit
  236.     end
  237.  
  238.     /* generate reply */
  239.     drop newmsg.
  240.     if symbol("msg.UMSCODE_ReplyName") = "VAR" then do
  241.       newmsg.UMSCODE_ToName = msg.UMSCODE_ReplyName
  242.     end; else
  243.       newmsg.UMSCODE_ToName = msg.UMSCODE_FromName
  244.  
  245.     /* test whether we should not reply */
  246.     if (find(msg.UMSCODE_Attributes,'receipt') ~= 0),  /* genaratec message */
  247.     | abbrev(upper(newmsg.UMSCODE_ToName),"MAILINGLIST "),  /* no reply to a mailinglist */
  248.     | ((ToName ~= '') & (upper(msg.UMSCODE_ToName) ~= ToName))
  249.     then
  250.       iterate
  251.  
  252.     if symbol("msg.UMSCODE_ReplyAddr") = "VAR" then do
  253.       newmsg.UMSCODE_ToAddr = msg.UMSCODE_ReplyAddr
  254.     end; else if symbol("msg.UMSCODE_FromAddr") = "VAR" then do
  255.       newmsg.UMSCODE_ToAddr = msg.UMSCODE_FromAddr
  256.     end
  257.     if useFolderAsReplyName then do
  258.       newmsg.UMSCODE_ReplyName = FolderName;
  259.     end; else if ReplyName ~= "" then do
  260.       newmsg.UMSCODE_ReplyName = ReplyName;
  261.     end
  262.     newmsg.UMSCODE_RefID   = msg.UMSCODE_MsgID
  263.     newmsg.UMSCODE_Attributes = "receipt"
  264.     newmsg.UMSCODE_Subject = Subject msg.UMSCODE_Subject
  265.     newmsg.UMSCODE_MsgText = "Hi" msg.UMSCODE_FromName ||"!" || '0A 0A'x || MessageText ||,
  266.     '0A 0A'x || 'Of course, this message has been generated automaticly :-)'
  267.  
  268.     if UMSWriteMsg(replyAccount, newmsg.) = 0 then
  269.       call CheckErr
  270.     else do
  271.       /* mark message as postponed and archived but unread */
  272.       call UMSSelectMsg(account,"U", FLAGS_PostArch, FLAG_Old, last)
  273.       i = i+1;
  274.     end;
  275.   end;
  276.   say i
  277.   return;
  278.  
  279. GetUMSConfigVar: procedure expose account replyAccount programname useReplyAccount
  280.   /* search order:
  281.    * User:  ProgName.varname.FolderName
  282.    * User:  ProgName.varname
  283.    * ReplyDeamon ProgName.varname
  284.    */
  285.   FolderName = arg(1);
  286.   if FolderName ~= '' then
  287.     Foldername = '.'FolderName;
  288.   varname = ProgramName || "."arg(2);
  289.   var = UMSReadConfig(account,varname || FolderName)
  290.   if (var = "") & (FolderName ~= "") then
  291.     var = UMSReadConfig(account,varname)
  292.   if (var = "") & useReplyAccount & (replyAccount ~= 0) then
  293.     var = UMSReadConfig(replyAccount,varname)
  294.   if (arg(3) = TRUE) then do
  295.     if (var = '') then do
  296.       say ProgramName || ": Configuration variable '" || varname || "' is missing!"
  297.       exit
  298.     end
  299.   end
  300.   return var
  301.  
  302. /*** Support ***/
  303.  
  304. CheckErr: procedure expose account replyAccount useReplyAccount
  305.   err = UMSErrNum(account)
  306.   if err ~= 0 then do
  307.     say "UMS Error #" || err || ": " || UMSErrTxt(account)
  308.   end; else if useReplyAccount then do
  309.     err = UMSErrNum(replyAccount)
  310.     if err ~= 0 then
  311.     say "UMS Error #" || err || ": " || UMSErrTxt(replyAccount)
  312.   end
  313. return
  314.